package com.tao.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mysql.cj.util.StringUtils;
import com.tao.common.constant.ProductConstant;
import com.tao.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.tao.gulimall.product.dao.AttrGroupDao;
import com.tao.gulimall.product.dao.CategoryDao;
import com.tao.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.tao.gulimall.product.entity.AttrGroupEntity;
import com.tao.gulimall.product.entity.CategoryEntity;
import com.tao.gulimall.product.service.CategoryService;
import com.tao.gulimall.product.vo.AttrGroupRelationVo;
import com.tao.gulimall.product.vo.AttrRespVo;
import com.tao.gulimall.product.vo.AttrVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tao.common.utils.PageUtils;
import com.tao.common.utils.Query;

import com.tao.gulimall.product.dao.AttrDao;
import com.tao.gulimall.product.entity.AttrEntity;
import com.tao.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Attr;

import javax.annotation.Resource;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Resource
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    @Resource
    private AttrGroupDao attrGroupDao;

    @Resource
    private CategoryDao categoryDao;

    @Resource
    private CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);
        // 保存基本数据
        this.save(attrEntity);
        if (attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId() != null){
            // 保存关联关系
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationDao.insert(relationEntity);
        }
    }

    /**
     * 查询基本属性信息
     *
     * @param params
     * @param categoryId
     * @param attrType
     * @return
     */
    @Override
    public PageUtils selectBaseList(Map<String, Object> params, Long categoryId, String attrType) {
        LambdaQueryWrapper<AttrEntity> lqw = new LambdaQueryWrapper<>();


        // 有无 categoryId
        if (categoryId != 0){
            lqw.eq(AttrEntity::getCatelogId,categoryId).eq(AttrEntity::getAttrType, attrType == "base" ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        }

        // 有无key
        String key = (String) params.get("key");
        if (!StringUtils.isNullOrEmpty(key)){
            lqw.and((wq -> {
                wq.eq(AttrEntity::getAttrId,key).or().like(AttrEntity::getAttrName,key);
            }));
        }

        // 先直接查询出来看看
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                lqw
        );

        PageUtils pageUtils = new PageUtils(page);
        // 需要得到分类分组的名称
        List<AttrRespVo> respVos = page.getRecords().stream().map((item) -> {
            AttrRespVo attrRespVo = new AttrRespVo();
            // 查询当前属性所属的分类分组, 只有base 类型的属性才有这个分组
            Long attrId = item.getAttrId();
            if("base".equals(attrType)){
                AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationDao.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
                if (relationEntity != null && relationEntity.getAttrGroupId() != null){
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
                    attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
            CategoryEntity categoryEntity = categoryDao.selectById(item.getCatelogId());
            if (categoryEntity != null){
                attrRespVo.setCatelogName(categoryEntity.getName());
            }
            BeanUtils.copyProperties(item, attrRespVo);
            return attrRespVo;
        }).collect(Collectors.toList());

        pageUtils.setList(respVos);

        return pageUtils;
    }

    /**
     * 获取当前属性的详细信息, 用于回显操作
     * @param attrId
     * @return
     */
	@Override
	public AttrRespVo getAttrInfo(Long attrId) {
        AttrRespVo attrRespVo = new AttrRespVo();
        // 先查询基本信息
        AttrEntity attrEntity = this.baseMapper.selectById(attrId);

        BeanUtils.copyProperties(attrEntity, attrRespVo);

        if(attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationDao.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
            if (relationEntity != null){
                Long attrGroupId = relationEntity.getAttrGroupId();
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
                attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
            }
        }
        // 查询 分组信息

        Long catelogId = attrEntity.getCatelogId();
        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
        if (categoryEntity != null){
            attrRespVo.setCatelogName(categoryEntity.getName());
        }
        attrRespVo.setCatelogId(catelogId);
        // 查询分类信息
        Long[] catelogPath = categoryService.findCatelogPath(catelogId);
        attrRespVo.setCatelogPath(catelogPath);

        return attrRespVo;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAttr(AttrVo attr) {
        // 保存基本信息
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        this.updateById(attrEntity);

        if(attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            // 修改关联关系
            AttrAttrgroupRelationEntity relation = new AttrAttrgroupRelationEntity();
            relation.setAttrGroupId(attr.getAttrGroupId());
            relation.setAttrId(attr.getAttrId());

            LambdaUpdateWrapper<AttrAttrgroupRelationEntity> lqw = new LambdaUpdateWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId());

            // 判断是修改还是新增呢
            Long count = attrAttrgroupRelationDao.selectCount(lqw);
            if(count > 0){
                attrAttrgroupRelationDao.update(relation, lqw);
            }else{
                attrAttrgroupRelationDao.insert(relation);
            }
        }
    }


    /**
     * 根据分组ID 查询当前分组关联的属性
     * @param attrGroupId
     * @return
     */
	@Override
    public List<AttrEntity> getRelaAttr(Long attrGroupId) {
        List<Long> attrIds = attrAttrgroupRelationDao.selectList(
                new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                        .eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId)
        ).stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        if (attrIds == null || attrIds.size() == 0){
            return null;
        }
        return this.listByIds(attrIds);
    }

    /**
     * 删除关联关系
     * @param vos
     */
    @Override
    public void deleteRelation(AttrGroupRelationVo[] vos) {

        // 先将传入的vos 转换为实体类, 规范使用
        List<AttrAttrgroupRelationEntity> relationEntities = Arrays.asList(vos).stream().map(item -> {
            AttrAttrgroupRelationEntity relation = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(item, relation);
            return relation;
        }).collect(Collectors.toList());

        // 批量删除, 手写sql , 这种批量删除的不要循环调用单个删除的方法, 而是采用批量删除的sql 语句
        attrAttrgroupRelationDao.deleteBatchByIds(relationEntities);


    }


    /**
     * 获取当前分组没有被关联的属性
     * @param params
     * @param attrGroupId
     * @return
     */
	@Override
	public PageUtils getNoRelaAttr(Map<String, Object> params, Long attrGroupId) {
        // 当前分组只能关联自己所属的分类中的所有属性
        // 1. 找到当前分组的分类
        Long catelogId = attrGroupDao.selectById(attrGroupId).getCatelogId();
        // 2. 现根据当前分类找到所有分组
        List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(new LambdaQueryWrapper<AttrGroupEntity>().eq(AttrGroupEntity::getCatelogId, catelogId));
        List<Long> groupIds = attrGroupEntities.stream().map(item -> {
            return item.getAttrGroupId();
        }).collect(Collectors.toList());
        // 3.找到被关联的所有属性
        List<AttrAttrgroupRelationEntity> relationAttrEntities = attrAttrgroupRelationDao.selectList(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().in(AttrAttrgroupRelationEntity::getAttrGroupId, groupIds));
        List<Long> relaAttrIds = relationAttrEntities.stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());
        // 4. 找到当前分类下的所有属性, 且排除被关联的属性id的
        LambdaQueryWrapper<AttrEntity> lqw = new LambdaQueryWrapper<>();
        // 查询所有基本属性, 不包括销售属性
        lqw.eq(AttrEntity::getCatelogId, catelogId).eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if(relaAttrIds != null && relaAttrIds.size() > 0){
            lqw.notIn(AttrEntity::getAttrId, relaAttrIds);
        }


        // 判断key 是否为null
        String key = (String) params.get("key");
        if(!StringUtils.isNullOrEmpty(key)){
            lqw.and(wrapper -> {
             wrapper.eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key);
            });
        }
        IPage<AttrEntity> page = page(new Query<AttrEntity>().getPage(params), lqw);
        PageUtils pageUtils = new PageUtils(page);
        return pageUtils;
        // 当前分组只能关联别的分组没有引用的属性
    }

}